import dateutil.parser
from rest_framework.viewsets import ModelViewSet
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
from rest_framework.authentication import TokenAuthentication
from apps.common.extension.customException import *
from apps.common.base.models import BaseModel
from apps.common.base.serializers import BaseSerializer
from apps.common.base.dao import BaseDao
from apps.common.utils.response import *
from apps.common.utils.fileHeader import *
from apps.common.utils.tools import *
from decimal import Decimal
import requests
import datetime
import os
import xlwt
import xlrd
import io
from django.http import FileResponse
import dateutil


class BaseViewSet(ModelViewSet):

    MODEL_CLASS = BaseModel
    DAO_CLASS = BaseDao
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly]
    filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter]

    @action(methods=['post'], detail=False)
    def createAction(self, request):
        params = getRequestParams(self.request)
        try:
            self.DAO_CLASS().create(params)
        except VerifyException as e:
            return Response(response_message(e.message))
        return Response(response_success('新增成功'))

    @action(methods=['post'], detail=False)
    def updateAction(self, request):
        params = getRequestParams(self.request)
        obj_id = params.get('obj_id')
        if isEmptyStr(obj_id):
            return Response(response_message('obj_id参数必填'))
        try:
            self.DAO_CLASS().update(obj_id, params)
        except VerifyException as e:
            return Response(response_message(e.message))
        return Response(response_success('更新成功'))

    @action(methods=['post'], detail=False)
    def deleteAction(self, request):
        params = getRequestParams(self.request)
        try:
            obj_ids = params.get('obj_ids')
            if type(obj_ids) != list:
                return Response(response_message('obj_ids应为数组类型'))
            self.DAO_CLASS().delete(obj_ids, params)
        except VerifyException as e:
            return Response(response_message(e.message))
        return Response(response_success('删除成功'))

    @action(methods=['post'], detail=False)
    def getItemById(self, request):
        params = getRequestParams(self.request)
        try:
            obj_id = params.get('obj_id')
            if not obj_id:
                return Response(response_message('obj_id参数必填'))
            obj = self.DAO_CLASS().findOneByObjId(obj_id)
            model = self.serializer_class(obj).data
        except VerifyException as e:
            return Response(response_message(e.message))
        return Response(response_success(model))
    
    @action(methods=['get'], detail=False)
    def exportAction(self, request):
        params = getRequestParams(self.request)
        try:
            obj_ids = params.get('obj_ids')
            filter_kw = params.get('filter_kw')
            exclude_kw = params.get('exclude_kw')
            order_bys = params.get('order_bys')
            _list = []
            if type(obj_ids) == list and len(obj_ids)>0:
                _list = self.DAO_CLASS().findAll().filter(id__in=obj_ids)
            else:
                # _list = self.DAO_CLASS().findAll().filter(**filter_kw).exclude(**exclude_kw).order_by(*order_bys)
                _list = self.filter_class(data=self.request.GET, queryset=self.get_queryset()).qs
            
            fieldData = self.serializer_class_export(_list, many=True).data
            # print('fieldData', fieldData)
            workbook = xlwt.Workbook(encoding = 'utf-8')
            worksheet = workbook.add_sheet(self.MODEL_CLASS._meta.verbose_name)

            style = xlwt.XFStyle()
            #设置样式
            alignment = xlwt.Alignment()
            # 水平位置：0x01(左端对齐)、0x02(水平方向上居中对齐)、0x03(右端对齐)
            alignment.horz = 0x01
            # 垂直方向：0x00(上端对齐)、 0x01(垂直方向上居中对齐)、0x02(底端对齐)
            alignment.vert = 0x01
            style.alignment = alignment
            #设置字体
            font = xlwt.Font()
            # font.bold = True
            style.font = font
            # 设置第一行
            for col_index, row in enumerate(self.exportFieldList):
                style1 = xlwt.XFStyle()
                font1 = xlwt.Font()
                font1.bold = True
                style1.font = font1
                worksheet.write(0, col_index, row.get('showName'), style1)
            row_index = 1
            # 设置表格数据
            for row_i, record in enumerate(fieldData):
                last_col_index = 0
                for col_index, row in enumerate(self.exportFieldList):
                    width = row.get('width') or 2000
                    key = row.get('key')
                    value = record.get(key)
                    if row.get('type') == 'String':
                        worksheet.write(row_index, col_index, value, style)
                        worksheet.col(col_index).width = width
                    elif row.get('type') == 'Record':
                        worksheet.write(row_index, col_index, record.get(row.get('relatedModel')).get(row.get('relatedKey')), style)
                        worksheet.col(col_index).width = width
                    elif row.get('type') == 'Datetime':
                        date_obj = dateutil.parser.parse(value)
                        worksheet.write(row_index, col_index, date_obj.strftime(row.get('format')), style)
                        worksheet.col(col_index).width = width
                    elif row.get('type') == 'Switch':
                        worksheet.write(row_index, col_index, '是' if value else '否', style)
                        worksheet.col(col_index).width = width
                    else:
                        worksheet.write(row_index, col_index, value, style)
                        worksheet.col(col_index).width = width
                row_index = row_index+1
            output = io.BytesIO()
            workbook.save(output)
            output.seek(0)
        except VerifyException as e:
            return Response(response_message(e.message))
        return FileResponse(output, as_attachment=True)